package cConfig

import (
	"github.com/nacos-group/nacos-sdk-go/clients"
	"github.com/nacos-group/nacos-sdk-go/clients/config_client"
	"github.com/nacos-group/nacos-sdk-go/common/constant"
	"github.com/nacos-group/nacos-sdk-go/vo"

	"gitee.com/csingo/cLog"
)

type NacosClient struct {
	Scheme    string `json:"scheme"`
	Host      string `json:"host"`
	Port      uint64 `json:"port"`
	Username  string `json:"username"`
	Password  string `json:"password"`
	Namespace string `json:"namespace"`
	Path      string `json:"path"`

	client config_client.IConfigClient
}

func (i *NacosClient) Driver() ConfigCenterDriver {
	return NacosDriver
}

func (i *NacosClient) InitClient() error {
	var err error

	if i.client != nil {
		return nil
	}

	i.client, err = clients.NewConfigClient(vo.NacosClientParam{
		ClientConfig: &constant.ClientConfig{
			NamespaceId:          i.Namespace,
			UpdateThreadNum:      0,
			NotLoadCacheAtStart:  true,
			UpdateCacheWhenEmpty: false,
			Username:             i.Username,
			Password:             i.Password,
		},
		ServerConfigs: []constant.ServerConfig{
			{
				IpAddr:      i.Host,
				ContextPath: i.Path,
				Port:        i.Port,
				Scheme:      i.Scheme,
			},
		},
	})

	return err
}

func (i *NacosClient) ReadConf(id, group string, explain bool) (result string, err error) {
	result, err = i.client.GetConfig(vo.ConfigParam{
		DataId: id,
		Group:  group,
	})
	if err != nil {
		cLog.WithContext(nil, map[string]any{
			"source": "cConfig.FileClient.ReadConf",
			"id":     id,
			"group":  group,
			"driver": i.Driver(),
		}, []cLog.Option{
			cLog.IncludePaths{},
		}).Error("配置读取失败")
		return
	} else {
		cLog.WithContext(nil, map[string]any{
			"source": "cConfig.FileClient.ReadConf",
			"id":     id,
			"group":  group,
			"driver": i.Driver(),
		}, []cLog.Option{
			cLog.IncludePaths{},
		}).Trace("配置读取成功")
	}

	if !explain {
		return
	}

	var counter int64
	var matches []*ExplainItem
	for counter = 0; counter < config_center_config.Layers; counter++ {
		matches, err = Explain(i, result)
		if err != nil {
			return
		}
		if len(matches) == 0 {
			break
		}
		for _, item := range matches {
			result = item.ReplaceFunc(result, item.Source, item.Target)
		}
	}

	return
}
